// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.MenuDao;
import com.liuxinlong.modules.entity.Menu;
import com.liuxinlong.modules.system.service.MenuService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 层级关系service接口实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022年5月12日
 */
@Service
@Slf4j
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuDao menuDao;

    @Override
    public List<Map<String, Object>> pageMenuInfo(Map<String, Object> queryParam) {
        List<Menu> originalList = menuDao.pageMenuList(queryParam);
        int startNum = (int) queryParam.get("startNum");
        List<Map<String, Object>> resultList = completeResult(originalList, startNum);
        return resultList;
    }

    @Override
    public int countMenu(Map<String, Object> queryParam) {
        return menuDao.getMenuCount(queryParam);
    }

    @Override
    public void addMenuInfo(Menu menu) {
        String parentId = menu.getParentId();
        String id = menu.getCode();
        if (!ObjectUtils.isEmpty(menuDao.selectById(id))) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，已存在相同菜单编码");
        }
        if (!StringUtils.equals(parentId, "0")) {
            Menu parentMenu = menuDao.selectById(parentId);
            if (ObjectUtils.isEmpty(parentMenu)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，父层级不存在");
            }
        }
        menu.setId(id);
        menuDao.insert(menu);
    }

    @Override
    public void updateMenuInfo(Menu menu) {
        String id = menu.getId();
        if (StringUtils.isEmpty(id)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，菜单id不存在");
        }
        Menu oldInfoMenu = menuDao.selectById(id);
        if (ObjectUtils.isEmpty(oldInfoMenu)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，菜单id不存在");
        }

        if (!StringUtils.equals(id, menu.getCode()) && !ObjectUtils.isEmpty(menuDao.selectById(menu.getCode()))) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，已存在相同菜单编码");
        }

        String parentId = menu.getParentId();

        if (!StringUtils.equals(parentId, oldInfoMenu.getParentId())) {
            if (!StringUtils.equals(parentId, "0")) {
                Menu parentMenu = menuDao.selectById(parentId);
                if (ObjectUtils.isEmpty(parentMenu)) {
                    throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "参数异常，父菜单不存在");
                }
            }
        }
        menuDao.updateById(menu);
    }

    @Override
    @Transactional
    public void deleteMenuInfo(String id) {
        menuDao.deleteById(id);
    }

    @Override
    public List<String> treeQueryMenu(String name) {
        Set<String> set = new HashSet<>();
//        List<Menu> menuList = menuDao.getMenuListByName(name);
//        for (Menu menu : menuList) {
//            set.add(menu.getParentId());
//        }
        return new ArrayList<>(set);
    }

    @Override
    public void exportMenuList(HttpServletResponse response) {
        Map<String, Map<String, String>> menuMap = menuDao.getMenuMap();
        ExcelData data = new ExcelData();
        data.setFileName("菜单信息列表导出excel.xlsx");
        List<Menu> menuList = menuDao.queryMenuList();
        String[] head = {"序号","菜单名称","父菜单", "排序", "权限分类", "编号", "权限编码"};
        data.setHead(head);
        String[][] dataList = new String[menuList.size()][head.length];
        int index = 0;
        for (Menu item : menuList) {
            dataList[index][0] = String.valueOf(index+1);
            dataList[index][1] = item.getName();
            dataList[index][2] = StringUtils.isNotEmpty(item.getParentId()) ? menuMap.containsKey(item.getParentId()) ? menuMap.get(item.getParentId()).get("name") : "" : "";
            dataList[index][3] = String.valueOf(item.getSort());

            dataList[index][4] = item.getRightType() == 1 ? "功能" : "菜单";
            dataList[index][5] = item.getCode();
            dataList[index][6] = item.getRightCode();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    /**
     * 补全数据
     *
     * @param originList 原始数据
     * @param startNum   起始数
     * @return 补全数据列表
     */
    private List<Map<String, Object>> completeResult(List<Menu> originList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (ObjectUtil.isEmpty(originList)) {
            return resultList;
        }
        Map<String, Map<String, String>> menuMap = menuDao.getMenuMap();
        int index = startNum + 1;
        for (Menu item : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(item);
            map.put("index", index);

            String parentId = item.getParentId();
            Map<String, String> parentInfo = menuMap.get(parentId);
            if (ObjectUtil.isNotEmpty(parentInfo)) {
                map.put("parentName", parentInfo.get("name"));
            }
            map.put("rightTypeName", item.getRightType() == 1 ? "功能" : "菜单");
            resultList.add(map);
            index++;
        }
        return resultList;
    }
}
